#ifndef _UI_SKIN_H_
#define _UI_SKIN_H_

#include "num/named_set.h"
#include "ui/ui_sprite.h"
#include "ui/sprite_bin.h"

namespace LuaPlus
{
	class	LuaObject;
}

namespace ui
{


struct	UISkinImage
{
	enum	SKIN_TILES
	{
		ST_TL,	ST_TC,	ST_TR,
		ST_CL,	ST_CC,	ST_CR,
		ST_BL,	ST_BC,	ST_BR,
		ST_IMAGE, ST_COUNT
	};

	void				LoadTile(SKIN_TILES Tile, const std::string& File);
	void				LoadImg(LuaPlus::LuaObject Obj);
	math::Vec2			GetTileSize();
	bool				IsValid() { if (SingleImage) return TileA[ST_IMAGE].IsValid(); else return TileA[ST_TL].IsValid(); };
	ui::UISprite		TileA[ST_COUNT];
	bool				SingleImage;
};

struct	UISkinData
{
	enum	IMAGE_STATES
	{
		IMAGE_OFF, 
		IMAGE_OVER,
		IMAGE_CLICK,
		IMAGE_C
	};
	std::string			Name;
	UISkinImage			ImageA[IMAGE_C];
	std::string			Sound;	// add this?
	bool				ClampSize;
};

struct	UISkinElement
{
	void		Tick(float dt) { Timer+=dt; };
	void		Render(UISkinData::IMAGE_STATES State, const math::Vec2& Pos, const math::Vec2& Size, COLOR c);
	math::Vec2	AdjustSize(const math::Vec2& OrigSize);
	std::string	Name;
	UISkinData*	pData;
	float		Timer;
	// cache actual information?
private:
	SpriteBin	RenderBin;
	math::Vec2	InvTileSize;
};

class	UISkin
{
public:
	static UISkin&	Instance();
	void		Load(const std::string& File);
	UISkinElement*	CreateElement(const std::string& Name);

	typedef void	(*FindSkinCB) (UISkinData* pSkinData, void* Data); // callback for effect param
	void			ForEach(FindSkinCB cb, void* Data);
private:
	UISkin() {};
	~UISkin() {};
	num::NamedSet<UISkinData*>		m_Elements;
};

}

#endif //_UI_SKIN_H_